<template>
  <CrudLayout>
    <!-- 搜索区域左侧 -->
    <template #search-left>
      <CrudSearchForm v-model="searchParams" :fields="searchFields" @search="handleSearch" @reset="handleSearchReset" />
    </template>

    <!-- 搜索区域右侧 -->
    <template #search-right>
      <CrudButton v-has="config.actions?.add?.permission" type="add" :icon="config.actions?.add?.icon" size="default"
        @click="handleAddBrand">
        {{ config.actions?.add?.text ?? '新增' }}
      </CrudButton>
    </template>

    <!-- 表格区域 -->
    <template #table-data>
      <CrudDataTable :data="tableData" :columns="tableColumns" v-loading="loading" :height="tableHeight"
        @selection-change="handleSelectionChange" stripe border />
    </template>

    <!-- 底部左侧 -->
    <template #foot-left>
      <CrudButton v-has="config.actions?.batchDelete?.permission" type="batch-delete"
        :icon="config.actions?.batchDelete?.icon" :disabled="selectedRows.length === 0" @click="handleBatchDelete">
        {{ config.actions?.batchDelete?.text ?? '批量删除' }}
      </CrudButton>
      <span v-if="selectedRows.length > 0" class="selection-info">
        已选择 {{ selectedRows.length }} 项
      </span>
    </template>

    <!-- 底部右侧 -->
    <template #footer-right>
      <CrudPagination v-model:current-page="pagination.current" v-model:page-size="pagination.size"
        :total="pagination.total" :page-sizes="config.pagination?.pageSizes" @size-change="handleSizeChange"
        @current-change="loadTableData" />
    </template>
  </CrudLayout>

  <!-- 弹窗容器 -->
  <div class="dialog-container">
    <!-- 编辑弹窗 -->
    <CrudFormDialog ref="editDialogRef" v-model:visible="editDialogVisible" :title="config.form.editTitle"
      :loading="editSubmitLoading" :form-config="formConfig" :model-value="editFormData"
      @update:model-value="handleEditFormUpdate" @submit="handleEditSubmit" @cancel="handleEditDialogClose" />

    <!-- 新增弹窗 -->
    <CrudFormDialog ref="addDialogRef" v-model:visible="addDialogVisible" :title="config.form.addTitle"
      :loading="addSubmitLoading" :form-config="formConfig" :model-value="addFormData"
      @update:model-value="handleAddFormUpdate" @submit="handleAddSubmit" @cancel="handleAddDialogClose" />

    <!-- 删除确认弹窗 -->
    <CrudConfirmDialog v-model:visible="deleteDialogVisible" :loading="deleteLoading" preset="deleteConfirm"
      :delete-type="deleteType" :target-name="getTargetName(deleteTarget)" :selected-count="selectedRows.length"
      @confirm="confirmDelete" @cancel="handleDeleteDialogClose" />
  </div>
</template>

<script setup lang="ts">
import type { SearchField } from '@/components/crudstyle/CrudSearchForm/index.vue'
import CrudSearchForm from '@/components/crudstyle/CrudSearchForm/index.vue'
import { ElMessage } from 'element-plus'
import { computed, onMounted, reactive, ref } from 'vue'

import type { TableRowData } from '@/components/cruddata/CrudDataTable/types'
import type { FormConfig } from '@/components/cruddata/CrudFormDialog/types'
import { useSettingStore, useUserStore } from '@/stores'
import config from './config'
import pageApi from './page.api'
import type { FormData, Pagination, Records } from './page.type'

// #region ===============================通用工具函数========================================
// 根据配置动态创建表单数据
const createFormData = () => {
  const formData: Record<string, unknown> = {}
  config.form.fields?.forEach((field: any) => {
    // 根据字段类型设置默认值
    if (field.type === 'select' && field.options?.length > 0) {
      formData[field.prop] = field.options[0].value
    } else if (field.type === 'number') {
      formData[field.prop] = 0
    } else if (field.type === 'switch') {
      formData[field.prop] = false
    } else if (field.type === 'checkbox') {
      formData[field.prop] = []
    } else {
      formData[field.prop] = ''
    }
  })
  return formData
}

// 根据配置动态创建搜索参数
const createSearchParams = () => {
  const searchData: Record<string, unknown> = {}
  config.search.fields?.forEach((field: any) => {
    searchData[field.prop] = ''
  })
  return searchData
}

// #endregion

// #region ===============================搜索区域========================================
// 设置仓库
const settingStore = useSettingStore()

// 从配置文件中获取搜索字段配置
const searchFields = config.search.fields as SearchField[]

// 搜索参数
const searchParams = ref<Record<string, unknown>>(createSearchParams())

// 搜索处理
const handleSearch = () => {
  // 重置页码并加载数据
  pagination.current = 1
  loadTableData()
}

// 重置搜索
const handleSearchReset = async () => {
  // 重新创建搜索参数
  searchParams.value = createSearchParams()
  await settingStore.triggerRefresh()
}

// #endregion

// mount前加载数据
onMounted(async () => {
  await loadTableData()
  // 可在进入页面时按需预加载
})

// #region ===============================表格数据========================================
// 表格数据加载中状态
const loading = ref(false)

// 表格数据
const tableData = ref<Records[]>([])

// 表格列配置，添加操作列
const tableColumns = computed(() => {
  const userButtons = userStore.userInfo?.buttons || []

  // 从配置文件中获取操作按钮定义
  const configActions = config.tableActions || []

  // 根据权限过滤按钮，并绑定处理函数
  const visibleActions = configActions
    .filter(action => !action.permission || userButtons.includes(action.permission))
    .map(action => ({
      ...action,
      handler: (row: TableRowData) => {
        // 根据 action 类型调用相应的处理函数
        if (action.action === 'edit') {
          handleEdit(row as unknown as Records)
        } else if (action.action === 'delete') {
          handleDelete(row as unknown as Records)
        }
      }
    }))

  // 如果没有可见按钮，不显示操作列
  if (visibleActions.length === 0) {
    return config.tableColumns
  }

  return [
    ...config.tableColumns,
    {
      type: 'actions',
      label: '操作',
      width: config.tableActionColumn.width,
      align: 'center',
      fixed: 'right',
      actions: visibleActions
    }
  ]
})

// 加载表格数据
const loadTableData = async () => {
  try {
    loading.value = true
    // 过滤空值
    const params = Object.fromEntries(
      Object.entries(searchParams.value).filter(([, value]) => value !== '' && value !== null && value !== undefined)
    )
    const { data } = await pageApi.getList(pagination.current, pagination.size, params)
    pagination.total = data.data.total
    tableData.value = data.data.records
    ElMessage.success(config.messages?.loadSuccess ?? '加载成功')
  } finally {
    loading.value = false
  }
}

// #endregion

// #region ===============================增删改查（操作列，新增按钮，删除按钮，批量删除按钮，分配角色按钮）========================================

// 表单配置
const formConfig = reactive<FormConfig>({
  labelWidth: config.form.labelWidth,
  rules: config.form.rules as FormConfig['rules'],
  fields: config.form.fields as FormConfig['fields']
})

// #region ===============================编辑按钮========================================
//获取用户信息
const userStore = useUserStore()
// 编辑对话框显示状态
const editDialogVisible = ref(false)
// 编辑对话框引用
const editDialogRef = ref<{ clearValidate: () => void } | null>(null)
// 编辑表单数据
const editFormData = reactive<FormData>(createFormData() as FormData)
// 编辑按钮提交加载状态
const editSubmitLoading = ref(false)
// 编辑表单数据更新处理
const handleEditFormUpdate = (value: FormData) => {
  Object.assign(editFormData, value)
}

// 编辑按钮点击
const handleEdit = (row: Records): void => {
  // 创建一个新的对象，确保响应性
  Object.assign(editFormData, row)
  editDialogVisible.value = true
}

// 编辑弹窗确认
const handleEditSubmit = async () => {
  editSubmitLoading.value = true
  try {
    await pageApi.update(editFormData)
    ElMessage.success(config.messages?.editSuccess ?? '修改成功！')
    await loadTableData()
    //只在编辑用户阶段使用：请删除
    if (userStore.userInfo?.id === editFormData.id) {
      await userStore.userInfoReq()
    }
  } finally {
    handleEditDialogClose()
    editSubmitLoading.value = false
  }
}

// 编辑弹窗关闭
const handleEditDialogClose = () => {
  editDialogVisible.value = false
  // 重新创建表单数据
  Object.assign(editFormData, createFormData())
  //清除校验
  editDialogRef.value?.clearValidate()
}

// #endregion

// #region ===============================新增按钮========================================
// 新增对话框显示状态
const addDialogVisible = ref(false)

// 新增对话框引用
const addDialogRef = ref<{ clearValidate: () => void } | null>(null)

// 新增表单数据
const addFormData = reactive<FormData>(createFormData() as FormData)

// 对话框提交加载状态
const addSubmitLoading = ref(false)

// 新增表单数据更新处理
const handleAddFormUpdate = (value: FormData) => {
  Object.assign(addFormData, value)
  // 删除不应该发送的字段
  delete addFormData.createdAt
  delete addFormData.updatedAt
}

// 新增按钮点击
const handleAddBrand = () => {
  addDialogVisible.value = true
}

// 新增弹窗确认
const handleAddSubmit = async () => {
  addSubmitLoading.value = true
  try {
    pagination.current = 1
    await pageApi.create(addFormData)
    ElMessage.success(config.messages?.addSuccess ?? '添加成功！')
    await loadTableData()
  } finally {
    handleAddDialogClose()
    addSubmitLoading.value = false
  }
}

// 新增弹窗关闭
const handleAddDialogClose = () => {
  addDialogVisible.value = false
  // 重新创建表单数据
  Object.assign(addFormData, createFormData())
  //清除校验
  addDialogRef.value?.clearValidate()
}

// #endregion

// #region ===============================删除按钮========================================

// 删除确认对话框相关状态
const deleteDialogVisible = ref(false)
const deleteLoading = ref(false)
const deleteType = ref<'single' | 'batch'>('single')
const deleteTarget = ref<Records | null>(null)
const selectedRows = ref<Records[]>([])

// 获取删除目标名称
const getTargetName = (target: unknown): string => {
  if (!target || !config.page.targetNameField) {
    return ''
  }
  // 修复：直接从 target 对象获取字段，而不是 target.data
  return (target as unknown as Record<string, unknown>)[config.page.targetNameField] as string || ''
}

// 删除按钮
// 单个删除
const handleDelete = (row: Records): void => {
  deleteType.value = 'single'
  deleteTarget.value = row
  deleteDialogVisible.value = true
}

// 批量删除
const handleBatchDelete = (): void => {
  if (selectedRows.value.length === 0) {
    ElMessage.warning('请选择要删除的数据')
    return
  }

  deleteType.value = 'batch'
  deleteTarget.value = null
  deleteDialogVisible.value = true
}

// 弹窗取消按钮
const handleDeleteDialogClose = (): void => {
  deleteDialogVisible.value = false
  deleteTarget.value = null
  deleteLoading.value = false
}

// 弹窗确认删除按钮
const confirmDelete = async (): Promise<void> => {
  deleteLoading.value = true
  try {
    if (deleteType.value === 'single') {
      // 单个删除
      if (!deleteTarget.value) {
        ElMessage.error('删除目标不存在')
        return
      }
      await pageApi.delete(deleteTarget.value.id as string)
      ElMessage.success('删除成功')
    } else {
      // 批量删除
      if (selectedRows.value.length === 0) {
        ElMessage.error('请选择要删除的数据')
        return
      }
      await pageApi.batchDelete(selectedRows.value.map(row => row.id as string))
      ElMessage.success('批量删除成功')
      selectedRows.value = []
    }
    loadTableData()
  } finally {
    handleDeleteDialogClose()
    deleteLoading.value = false
  }
}


// 处理表格选择列变化
const handleSelectionChange = (selection: TableRowData[]): void => {
  // 将TableRowData类型转换为Records类型
  selectedRows.value = selection as unknown as Records[]
  console.log('选中的数据:', selection)
}

// #endregion

// #endregion

// #region ===============================底部分页组件========================================

// 分页信息
const pagination = reactive<Pagination>({
  current: 1,
  size: config.pagination?.defaultPageSize || 10,
  total: 0
})

// 处理页面展示数据数量size变化
const handleSizeChange = (): void => {
  pagination.current = 1
  loadTableData()
}

// #endregion

// #region ===============================其他通用函数========================================

// 计算表格高度
const tableHeight = computed(() => {
  // 页面可用高度 = 100vh - 64px(header) - 48px(MainContent padding)
  const pageHeight = window.innerHeight - 64 - 48

  // 搜索区域高度：padding(20px*2) + margin-bottom(20px) + 内容高度(约40px) = 80px
  const searchSectionHeight = 80

  // 表格底部操作区域高度：padding(15px*2) + border(1px) + 内容高度(约30px) = 61px
  const tableFooterHeight = 61

  // 预留一些空间避免滚动条
  const reservedHeight = 10

  const calculatedHeight = pageHeight - searchSectionHeight - tableFooterHeight - reservedHeight

  // 确保最小高度
  const finalHeight = Math.max(calculatedHeight, 300)

  return `${finalHeight}px`
})

// #endregion


</script>

<style scoped lang="scss"></style>
